<!DOCTYPE html>
<html lang="en-us">
  <head>

    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    
<meta charset="UTF-8">
<title>Combining Filters | Elasticsearch: The Definitive Guide [2.x] | Elastic</title>
<link rel="home" href="index.html" title="Elasticsearch: The Definitive Guide [2.x]">
<link rel="up" href="structured-search.html" title="Structured Search">
<link rel="prev" href="_finding_exact_values.html" title="Finding Exact Values">
<link rel="next" href="_finding_multiple_exact_values.html" title="Finding Multiple Exact Values">
<meta name="DC.type" content="Learn/Docs/Legacy/Elasticsearch/Definitive Guide/2.x">
<meta name="DC.subject" content="Elasticsearch">
<meta name="DC.identifier" content="2.x">
<meta name="robots" content="noindex,nofollow">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="https://cdn.optimizely.com/js/18132920325.js"></script>
    <link rel="apple-touch-icon" sizes="57x57" href="/apple-icon-57x57.png">
    <link rel="apple-touch-icon" sizes="60x60" href="/apple-icon-60x60.png">
    <link rel="apple-touch-icon" sizes="72x72" href="/apple-icon-72x72.png">
    <link rel="apple-touch-icon" sizes="76x76" href="/apple-icon-76x76.png">
    <link rel="apple-touch-icon" sizes="114x114" href="/apple-icon-114x114.png">
    <link rel="apple-touch-icon" sizes="120x120" href="/apple-icon-120x120.png">
    <link rel="apple-touch-icon" sizes="144x144" href="/apple-icon-144x144.png">
    <link rel="apple-touch-icon" sizes="152x152" href="/apple-icon-152x152.png">
    <link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png">
    <link rel="icon" type="image/png" href="/favicon-32x32.png" sizes="32x32">
    <link rel="icon" type="image/png" href="/android-chrome-192x192.png" sizes="192x192">
    <link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96">
    <link rel="icon" type="image/png" href="/favicon-16x16.png" sizes="16x16">
    <link rel="manifest" href="/manifest.json">
    <meta name="apple-mobile-web-app-title" content="Elastic">
    <meta name="application-name" content="Elastic">
    <meta name="msapplication-TileColor" content="#ffffff">
    <meta name="msapplication-TileImage" content="/mstile-144x144.png">
    <meta name="theme-color" content="#ffffff">
    <meta name="naver-site-verification" content="936882c1853b701b3cef3721758d80535413dbfd">
    <meta name="yandex-verification" content="d8a47e95d0972434">
    <meta name="localized" content="true">
    <meta name="st:robots" content="follow,index">
    <meta property="og:image" content="https://www.elastic.co/static/images/elastic-logo-200.png">
    <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
    <link rel="icon" href="/favicon.ico" type="image/x-icon">
    <link rel="apple-touch-icon-precomposed" sizes="64x64" href="/favicon_64x64_16bit.png">
    <link rel="apple-touch-icon-precomposed" sizes="32x32" href="/favicon_32x32.png">
    <link rel="apple-touch-icon-precomposed" sizes="16x16" href="/favicon_16x16.png">
    <!-- Give IE8 a fighting chance -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
    <link rel="stylesheet" type="text/css" href="/guide/static/styles.css">
  </head>

  <!--© 2015-2021 Elasticsearch B.V. Copying, publishing and/or distributing without written permission is strictly prohibited.-->

  <body>
    <!-- Google Tag Manager -->
    <script>dataLayer = [];</script><noscript><iframe src="//www.googletagmanager.com/ns.html?id=GTM-58RLH5" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
    <script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= '//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-58RLH5');</script>
    <!-- End Google Tag Manager -->

    <!-- Global site tag (gtag.js) - Google Analytics -->
    <script async src="https://www.googletagmanager.com/gtag/js?id=UA-12395217-16"></script>
    <script>
      window.dataLayer = window.dataLayer || [];
      function gtag(){dataLayer.push(arguments);}
      gtag('js', new Date());
      gtag('config', 'UA-12395217-16');
    </script>

    <!--BEGIN QUALTRICS WEBSITE FEEDBACK SNIPPET-->
    <script type="text/javascript">
      (function(){var g=function(e,h,f,g){
      this.get=function(a){for(var a=a+"=",c=document.cookie.split(";"),b=0,e=c.length;b<e;b++){for(var d=c[b];" "==d.charAt(0);)d=d.substring(1,d.length);if(0==d.indexOf(a))return d.substring(a.length,d.length)}return null};
      this.set=function(a,c){var b="",b=new Date;b.setTime(b.getTime()+6048E5);b="; expires="+b.toGMTString();document.cookie=a+"="+c+b+"; path=/; "};
      this.check=function(){var a=this.get(f);if(a)a=a.split(":");else if(100!=e)"v"==h&&(e=Math.random()>=e/100?0:100),a=[h,e,0],this.set(f,a.join(":"));else return!0;var c=a[1];if(100==c)return!0;switch(a[0]){case "v":return!1;case "r":return c=a[2]%Math.floor(100/c),a[2]++,this.set(f,a.join(":")),!c}return!0};
      this.go=function(){if(this.check()){var a=document.createElement("script");a.type="text/javascript";a.src=g;document.body&&document.body.appendChild(a)}};
      this.start=function(){var a=this;window.addEventListener?window.addEventListener("load",function(){a.go()},!1):window.attachEvent&&window.attachEvent("onload",function(){a.go()})}};
      try{(new g(100,"r","QSI_S_ZN_emkP0oSe9Qrn7kF","https://znemkp0ose9qrn7kf-elastic.siteintercept.qualtrics.com/WRSiteInterceptEngine/?Q_ZID=ZN_emkP0oSe9Qrn7kF")).start()}catch(i){}})();
    </script><div id="ZN_emkP0oSe9Qrn7kF"><!--DO NOT REMOVE-CONTENTS PLACED HERE--></div>
    <!--END WEBSITE FEEDBACK SNIPPET-->

    <div id="elastic-nav" style="display:none;"></div>
    <script src="https://www.elastic.co/elastic-nav.js"></script>

    <!-- Subnav -->
    <div>
      <div>
        <div class="tertiary-nav d-none d-md-block">
          <div class="container">
            <div class="p-t-b-15 d-flex justify-content-between nav-container">
              <div class="breadcrum-wrapper"><span><a href="/guide/" style="font-size: 14px; font-weight: 600; color: #000;">Docs</a></span></div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <div class="main-container">
      <section id="content">
        <div class="content-wrapper">

          <section id="guide" lang="en">
            <div class="container">
              <div class="row">
                <div class="col-xs-12 col-sm-8 col-md-8 guide-section">
                  <!-- start body -->
                  <div class="page_header">
<p>
  <strong>WARNING</strong>: The 2.x versions of Elasticsearch have passed their
  <a href="https://www.elastic.co/support/eol">EOL dates</a>. If you are running
  a 2.x version, we strongly advise you to upgrade.
</p>
<p>
  This documentation is no longer maintained and may be removed. For the latest
  information, see the <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html">current
  Elasticsearch documentation</a>.
</p>
</div>
<div id="content">
<div class="breadcrumbs">
<span class="breadcrumb-link"><a href="index.html">Elasticsearch: The Definitive Guide [2.x]</a></span>
»
<span class="breadcrumb-link"><a href="search-in-depth.html">Search in Depth</a></span>
»
<span class="breadcrumb-link"><a href="structured-search.html">Structured Search</a></span>
»
<span class="breadcrumb-node">Combining Filters</span>
</div>
<div class="navheader">
<span class="prev">
<a href="_finding_exact_values.html">« Finding Exact Values</a>
</span>
<span class="next">
<a href="_finding_multiple_exact_values.html">Finding Multiple Exact Values »</a>
</span>
</div>
<div class="section">
<div class="titlepage"><div><div>
<h2 class="title">
<a id="combining-filters"></a>Combining Filters<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch-definitive-guide/edit/2.x/080_Structured_Search/10_compoundfilters.asciidoc">edit</a>
</h2>
</div></div></div>
<p>The previous two examples showed a single filter in use.
In practice, you will probably need to filter on multiple values or fields.
For example, how would you express this SQL in Elasticsearch?</p>
<div class="pre_wrapper lang-sql">
<pre class="programlisting prettyprint lang-sql">SELECT product
FROM   products
WHERE  (price = 20 OR productID = "XHDK-A-1293-#fJ3")
  AND  (price != 30)</pre>
</div>
<p>In these situations, you will need to use a <code class="literal">bool</code> query
inside the <code class="literal">constant_score</code> query.  This allows us to build
filters that can have multiple components in boolean combinations.</p>
<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="bool-filter"></a>Bool Filter<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch-definitive-guide/edit/2.x/080_Structured_Search/10_compoundfilters.asciidoc">edit</a>
</h3>
</div></div></div>
<p>Recall that the <code class="literal">bool</code> query is composed of four sections:</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">{
   "bool" : {
      "must" :     [],
      "should" :   [],
      "must_not" : [],
      "filter":    []
   }
}</pre>
</div>
<div class="variablelist">
<dl class="variablelist">
<dt>
<span class="term">
<code class="literal">must</code>
</span>
</dt>
<dd>
All of these clauses <em>must</em> match. The equivalent of <code class="literal">AND</code>.
</dd>
<dt>
<span class="term">
<code class="literal">must_not</code>
</span>
</dt>
<dd>
All of these clauses <em>must not</em> match. The equivalent of <code class="literal">NOT</code>.
</dd>
<dt>
<span class="term">
<code class="literal">should</code>
</span>
</dt>
<dd>
At least one of these clauses must match. The equivalent of <code class="literal">OR</code>.
</dd>
<dt>
<span class="term">
<code class="literal">filter</code>
</span>
</dt>
<dd>
Clauses that <em>must</em> match, but are run in non-scoring, filtering mode.
</dd>
</dl>
</div>
<p>In this secondary boolean query, we can ignore the <code class="literal">filter</code> clause: the queries
are already running in non-scoring mode, so the extra <code class="literal">filter</code> clause is useless.</p>
<div class="note admon">
<div class="icon"></div>
<div class="admon_content">
<p>Each section of the <code class="literal">bool</code> filter is optional (for example, you can have a <code class="literal">must</code>
clause and nothing else), and each section can contain a single query or an
array of queries.</p>
</div>
</div>
<p>To replicate the preceding SQL example, we will take the two <code class="literal">term</code> queries that
we used
 previously and
place them inside the <code class="literal">should</code> clause of a <code class="literal">bool</code> query, and add another clause
to deal with the <code class="literal">NOT</code> condition:</p>
<div class="pre_wrapper lang-sense">
<pre class="programlisting prettyprint lang-sense">GET /my_store/products/_search
{
   "query" : {
      "constant_score" : { <a id="CO45-1"></a><i class="conum" data-value="1"></i>
         "filter" : {
            "bool" : {
              "should" : [
                 { "term" : {"price" : 20}}, <a id="CO45-2"></a><i class="conum" data-value="2"></i>
                 { "term" : {"productID" : "XHDK-A-1293-#fJ3"}} <a id="CO45-3"></a><i class="conum" data-value="2"></i>
              ],
              "must_not" : {
                 "term" : {"price" : 30} <a id="CO45-4"></a><i class="conum" data-value="3"></i>
              }
           }
         }
      }
   }
}</pre>
</div>
<div class="sense_widget" data-snippet="snippets/080_Structured_Search/10_Bool_filter.json"></div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO45-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p>Note that we still need to use a <code class="literal">constant_score</code> query to wrap everything with its
<code class="literal">filter</code> clause. This is what enables non-scoring mode</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO45-2"><i class="conum" data-value="2"></i></a><a href="#CO45-3"></a></p>
</td>
<td align="left" valign="top">
<p>These two <code class="literal">term</code> queries are <em>children</em> of the <code class="literal">bool</code> query, and since they
are placed inside the <code class="literal">should</code> clause, at least one of them needs to match.</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO45-4"><i class="conum" data-value="3"></i></a></p>
</td>
<td align="left" valign="top">
<p>If a product has a price of <code class="literal">30</code>, it is automatically excluded because it
matches a <code class="literal">must_not</code> clause.</p>
</td>
</tr>
</table>
</div>
<p>Notice how boolean is placed inside the <code class="literal">constant_score</code>, but the individual term
queries are just placed in the <code class="literal">should</code> and <code class="literal">must_not</code>.  Because everything is wrapped
with the <code class="literal">constant_score</code>, the rest of the queries are executing in filtering mode.</p>
<p>Our search results return two hits, each document satisfying a different clause
in the <code class="literal">bool</code> query:</p>
<div class="pre_wrapper lang-json">
<pre class="programlisting prettyprint lang-json">"hits" : [
    {
        "_id" :     "1",
        "_score" :  1.0,
        "_source" : {
          "price" :     10,
          "productID" : "XHDK-A-1293-#fJ3" <a id="CO46-1"></a><i class="conum" data-value="1"></i>
        }
    },
    {
        "_id" :     "2",
        "_score" :  1.0,
        "_source" : {
          "price" :     20, <a id="CO46-2"></a><i class="conum" data-value="2"></i>
          "productID" : "KDKE-B-9947-#kL5"
        }
    }
]</pre>
</div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO46-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p>Matches the <code class="literal">term</code> query for <code class="literal">productID = "XHDK-A-1293-#fJ3"</code></p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO46-2"><i class="conum" data-value="2"></i></a></p>
</td>
<td align="left" valign="top">
<p>Matches the <code class="literal">term</code> query for <code class="literal">price = 20</code></p>
</td>
</tr>
</table>
</div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_nesting_boolean_queries"></a>Nesting Boolean Queries<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch-definitive-guide/edit/2.x/080_Structured_Search/10_compoundfilters.asciidoc">edit</a>
</h3>
</div></div></div>
<p>You can already see how nesting boolean queries together can give rise to more
sophisticated boolean logic.  If you need to perform more complex operations, you
can continue nesting boolean queries in any combination, giving rise to
arbitrarily complex boolean logic.</p>
<p>For example, if we have this SQL statement:</p>
<div class="pre_wrapper lang-sql">
<pre class="programlisting prettyprint lang-sql">SELECT document
FROM   products
WHERE  productID      = "KDKE-B-9947-#kL5"
  OR (     productID = "JODL-X-1937-#pV7"
       AND price     = 30 )</pre>
</div>
<p>We can translate it into a pair of nested <code class="literal">bool</code> filters:</p>
<div class="pre_wrapper lang-sense">
<pre class="programlisting prettyprint lang-sense">GET /my_store/products/_search
{
   "query" : {
      "constant_score" : {
         "filter" : {
            "bool" : {
              "should" : [
                { "term" : {"productID" : "KDKE-B-9947-#kL5"}}, <a id="CO47-1"></a><i class="conum" data-value="1"></i>
                { "bool" : { <a id="CO47-2"></a><i class="conum" data-value="1"></i>
                  "must" : [
                    { "term" : {"productID" : "JODL-X-1937-#pV7"}}, <a id="CO47-3"></a><i class="conum" data-value="2"></i>
                    { "term" : {"price" : 30}} <a id="CO47-4"></a><i class="conum" data-value="2"></i>
                  ]
                }}
              ]
           }
         }
      }
   }
}</pre>
</div>
<div class="sense_widget" data-snippet="snippets/080_Structured_Search/10_Bool_filter.json"></div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO47-1"><i class="conum" data-value="1"></i></a><a href="#CO47-2"></a></p>
</td>
<td align="left" valign="top">
<p>Because the <code class="literal">term</code> and the <code class="literal">bool</code> are sibling clauses inside the
Boolean <code class="literal">should</code>, at least one of these queries must match for a document
to be a hit.</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO47-3"><i class="conum" data-value="2"></i></a><a href="#CO47-4"></a></p>
</td>
<td align="left" valign="top">
<p>These two <code class="literal">term</code> clauses are siblings in a <code class="literal">must</code> clause, so they both
have to match for a document to be returned as a hit.</p>
</td>
</tr>
</table>
</div>
<p>The results show us two documents, one matching each of the <code class="literal">should</code> clauses:</p>
<div class="pre_wrapper lang-json">
<pre class="programlisting prettyprint lang-json">"hits" : [
    {
        "_id" :     "2",
        "_score" :  1.0,
        "_source" : {
          "price" :     20,
          "productID" : "KDKE-B-9947-#kL5" <a id="CO48-1"></a><i class="conum" data-value="1"></i>
        }
    },
    {
        "_id" :     "3",
        "_score" :  1.0,
        "_source" : {
          "price" :      30, <a id="CO48-2"></a><i class="conum" data-value="2"></i>
          "productID" : "JODL-X-1937-#pV7" <a id="CO48-3"></a><i class="conum" data-value="2"></i>
        }
    }
]</pre>
</div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO48-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p>This <code class="literal">productID</code> matches the <code class="literal">term</code> in the first <code class="literal">bool</code>.</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO48-2"><i class="conum" data-value="2"></i></a><a href="#CO48-3"></a></p>
</td>
<td align="left" valign="top">
<p>These two fields match the <code class="literal">term</code> filters in the nested <code class="literal">bool</code>.</p>
</td>
</tr>
</table>
</div>
<p>This was a simple example, but it demonstrates how Boolean queries can be
used as building blocks to construct complex logical conditions.</p>
</div>

</div>
<div class="navfooter">
<span class="prev">
<a href="_finding_exact_values.html">« Finding Exact Values</a>
</span>
<span class="next">
<a href="_finding_multiple_exact_values.html">Finding Multiple Exact Values »</a>
</span>
</div>
</div>

                  <!-- end body -->
                </div>
                <div class="col-xs-12 col-sm-4 col-md-4" id="right_col">
                  <div id="rtpcontainer" style="display: block;">
                    <div class="mktg-promo">
                      <h3>Most Popular</h3>
                      <ul class="icons">
                        <li class="icon-elasticsearch-white"><a href="https://www.elastic.co/webinars/getting-started-elasticsearch?baymax=default&amp;elektra=docs&amp;storm=top-video">Get Started with Elasticsearch: Video</a></li>
                        <li class="icon-kibana-white"><a href="https://www.elastic.co/webinars/getting-started-kibana?baymax=default&amp;elektra=docs&amp;storm=top-video">Intro to Kibana: Video</a></li>
                        <li class="icon-logstash-white"><a href="https://www.elastic.co/webinars/introduction-elk-stack?baymax=default&amp;elektra=docs&amp;storm=top-video">ELK for Logs &amp; Metrics: Video</a></li>
                      </ul>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </section>

        </div>


<div id="elastic-footer"></div>
<script src="https://www.elastic.co/elastic-footer.js"></script>
<!-- Footer Section end-->

      </section>
    </div>

<script src="/guide/static/jquery.js"></script>
<script type="text/javascript" src="/guide/static/docs.js"></script>
<script type="text/javascript">
  window.initial_state = {}</script>
  </body>
</html>
